/*
 * Name 		: Chang Hyun Park
 * Student ID	: 2007******
 * Major		: Computer Engineering
 * Year			: 3rd Year
 * Subject		: File Management
 * Filename		: otheralgorithms.c
 */

#include "header.h"

void init_arrays(int** lru_buf, int** mru_buf, int*** lfu_buf)
{
	int** temp;
	*lru_buf = (int*)malloc(sizeof(int)*buffer_size);
	*mru_buf = (int*)malloc(sizeof(int)*buffer_size);
	*lfu_buf = (int**)malloc(sizeof(int*)*2);
	temp=*lfu_buf;
		temp[0] = (int*)malloc(sizeof(int)*buffer_size);
		temp[1] = (int*)malloc(sizeof(int)*buffer_size);
}

int hit_lmru(int num, int* buf)
{
    int i, index, j;
    for(i=0; i<buffer_size; i++)
    {
        if(buf[i] == num)
            return (i);
    }
    return -1;
}

int hit_lfu(int num, int** buf)
{
    int i, index, j;
    for(i=0; i<buffer_size; i++)
	{
    	if(buf[0][i] == num)
		{
			buf[1][i]++;
        	return (i);
		}
    }
    return -1;
}

int lru(int num, int* lru_buf, int* buf, int lru_process_count)
{
    int i, temp, index;
    index = hit_lmru(num, lru_buf);
    if(index >= 0) {
        temp = lru_buf[index];
        for(i=index; i>0; i--)
            lru_buf[i] = lru_buf[i-1];
        lru_buf[0] = temp;
       // lru_hit_count++;
        return 1;
    }
    else if(index == -1) {
        for(i=buffer_size-1; i>0; i--)
            lru_buf[i] = lru_buf[i-1];
        lru_buf[0] = buf[lru_process_count];
        //lru_miss_count++;
        return 0;
    }
    return -1;
}

int mru(int num, int* mru_buf, int* buf, int mru_process_count)
{
	int i, temp, index;
	index = hit_lmru(num, mru_buf);
	if(index>= 0)
	{
		temp= mru_buf[index];
		for(i=index;i>0;i--)
			mru_buf[i] = mru_buf[i-1];
		mru_buf[0] = temp;
		//mru_hit_count++;
		return 1;
	}
	else if(index==-1)
	{
		mru_buf[0] = buf[mru_process_count];
		//mru_miss_count++;
		return 0;
	}
	return -1;
}

int lfu(int num, int** lfu_buf, int* buf, int lfu_process_count)
{
	int i, temp_index, temp, temp_f, index;
	index = hit_lfu(num, lfu_buf);
	if(index>= 0)
	{
		temp= lfu_buf[0][index];
		temp_f= lfu_buf[1][index];
		for(i=index;i>0;i--)
		{
			lfu_buf[0][i] = lfu_buf[0][i-1];
			lfu_buf[1][i] = lfu_buf[1][i-1];
		}
		lfu_buf[0][0] = temp;
		lfu_buf[1][0] = temp_f;
		//lfu_hit_count++;
		return 1;
	}
	else if(index == -1)
	{
		temp_index=find_min(lfu_buf);
		for(i=temp_index;i>0;i--)
		{
			lfu_buf[0][i]=lfu_buf[0][i-1];
			lfu_buf[1][i]=lfu_buf[1][i-1];
		}
		lfu_buf[0][0] = buf[lfu_process_count];
		lfu_buf[1][0] = 1;
		//lfu_miss_count++;
		return 0;
	}

}

int find_min(int** lfu_buf)
{
	int i=0;
	int temp, min;
	min=lfu_buf[1][buffer_size-1];
	temp = buffer_size-1;
	for(i=buffer_size-2;i>=0;i--)
	{
		if(lfu_buf[1][i]<min)
		{
			min=lfu_buf[1][i];
			temp = i;
		}
	}
	return temp;
}
